/**
 * 文件上传
 */
const express = require('express');
const fs = require('fs/promises');
const path = require('path');
const multer = require('multer');

const { CODE_OK, CODE_BAD_REQUEST } = require('@root/config/index');
const { poolPromise } = require('@root/db/index');

const router = express.Router();

/**
 *  验证是否已经上传
 */
router.post('/verify', async (req, res, next) => {
  try {
    const { file_name } = req.body;
    let list = await findFileInfo(file_name);
    if (list.length > 0) {
      return res.status(CODE_OK).json({
        code: CODE_OK,
        msg: '已经上传',
        data: list[0],
      });
    }

    res.status(CODE_OK).json({
      code: CODE_OK,
      msg: '未上传',
      data: null,
    });
  } catch (error) {
    next(error);
  }
});
const uploadBaseDir = path.resolve('./public'); // 上传文件根目录
const upload = multer({});

/**
 * @descriptions 写入文件
 * @param {File} file
 * @param {string} [dir] 上传目录 默认 /upload
 * @returns Promise<{filename: string, fileSuffix: string, url: string}>
 */
function writeFile(file, dir) {
  return new Promise((resolve, reject) => {
    try {
      const { originalname, buffer } = file;
      const fileSuffix = path.extname(originalname); // 文件后缀
      const filename = `${path.basename(originalname, fileSuffix)}`; // 文件名
      const uploadDir = uploadBaseDir + dir; // 上传的文件目录
      const uploadFilePath = path.join(uploadDir, filename + fileSuffix); // 上传文件路径
      fs.writeFile(uploadFilePath, buffer).then(() => {
        let filePath = `${dir}/${filename}${fileSuffix}`;
        resolve({
          filename,
          fileSuffix,
          filePath,
          fileUrl: `http://localhost:10003${filePath}`,
        });
      });
    } catch (error) {
      reject(error);
    }
  });
}

/**
 * @descriptions 查找文件信息
 * @param {string} file_name 文件名 后面替换为 file_hash
 */
async function findFileInfo(file_name) {
  let file_select_sql = `select * from file_resources where file_name = ?`;
  let [list] = await poolPromise.execute(file_select_sql, [file_name]);
  list.forEach((item) => (item.file_url = `http://localhost:10003${item.file_url}`));
  return list;
}

/**
 * 单个上传
 */
router.post('/file', upload.single('file'), async (req, res, next) => {
  try {
    if (!req.file) {
      return res.status(CODE_BAD_REQUEST).json({
        code: CODE_BAD_REQUEST,
        msg: 'file参数不能为空',
        data: null,
      });
    }
    const { originalname, size } = req.file;
    let list = await findFileInfo(originalname);
    if (list.length > 0) {
      return res.status(CODE_OK).json({
        code: CODE_OK,
        msg: '已存在,直接返回',
        data: list[0],
      });
    }
    // dir : 以根目录为基础路径进行文件的路径拼接
    const { type = 'all' } = req.body;
    let dir = `/uploads/${type}`;
    let result = await writeFile(req.file, dir);
    let file_insert_sql = `insert into file_resources (file_hash, file_name,file_size, file_url, file_type) values (?, ?, ?, ?, ?)`;
    await poolPromise.execute(file_insert_sql, [
      Date.now(),
      originalname,
      size,
      result.filePath,
      type,
    ]);

    // 查询新增的文件,并返回
    let list2 = await findFileInfo(originalname);
    if (list2.length > 0) {
      return res.status(CODE_OK).json({
        code: CODE_OK,
        msg: 'ok',
        data: list2[0],
      });
    }
  } catch (error) {
    next(error);
  }

  // const filePath = `${uploadBaseDir}/${name}`;
  // const fileStream = fs.createWriteStream(filePath);
  // req.files.file.pipe(fileStream);
});

/**
 * 批量上传
 */
router.post('/files', upload.array('file'), async (req, res, next) => {
  try {
    // dir : 以根目录为基础路径进行文件的路径拼接
    const { dir = '/uploads' } = req.body;
    let pall = [];
    req.files.forEach((file) => {
      pall.push(writeFile(file, dir));
    });
    let result = await Promise.all(pall);
    return res.status(CODE_BAD_REQUEST).json({
      code: CODE_BAD_REQUEST,
      msg: 'ok',
      data: result,
    });
  } catch (error) {
    next(error);
  }
});

module.exports = router;
